
/* Generated by Interface Builder */

#import "Server.h"
#import "Protos.h"
#import "Proto.h"
#import "Main.h"
#import <appkit/Panel.h>
#import <appkit/SavePanel.h>
#import <appkit/Application.h>
#import <appkit/Listener.h>
#import <appkit/Speaker.h>
#import <appkit/Pasteboard.h>
#import <appkit/Button.h>
#import <appkit/PopUpList.h>
#import <appkit/Matrix.h>
#import <objc/List.h>
#import <stdio.h>
#import <strings.h>
#import <sys/types.h>
#import <sys/stat.h>
#import <sys/param.h>
#import <mach.h>

@implementation Server

+ new
{
	self = [super new];
	[NXApp loadNibSection:"Server.nib" owner:self];
	savepanel = [SavePanel new];
	// Add the view with the type pop-up-list and opening choice to save panel.
	[auxview removeFromSuperview];
	[savepanel setAccessoryView:auxview];
	return self;
}

// Add a type to the list.
- addtype:(char *)name
{
	[typelist addItem:name];
	return self;
}

// Set up the type list from the list of proto's.
- inittypes:list
{
	int i;
	int count = [list count];
	for (i=0; i<count; i++)
		[self addtype:[[list objectAt:i] typename]];
	return self;
}

/*
If path is a directory, then dir is a copy of path. Otherwise, dir contains the directory part of path.
*/
void get_directory(char *dir, char *path)
{
	struct stat buf;
	strcpy(dir, path);
	stat(dir, &buf);
	if ((buf.st_mode & S_IFDIR) == 0) *rindex(dir, '/') = '\0';
}

// When service is activated, the current directory is in the pasteboard.
- get_dir_from_pb:(char *)dir:(id)pb
{
	int length;
	char *data;
	const char *const *types;
	int hasType, i;

	// Don't really need to check for the type, as it must always be
	// present if a service was invoked.
	types = [pb types];
	hasType=0;
	for (i=0; !hasType && types[i] ; i++) 
		if (!strcmp(types[i], NXFilenamePboardType)) hasType=1;
	if (hasType)
	{
		[pb readType:NXFilenamePboardType data:&data length:&length];
		get_directory(dir, data);
		return self;
	}
	else
		return nil;
}

/*
Set the type of the file to be created. Sets the save panel's type and sets the type pop-up-list and open default.
*/
- setfiletype:(char *)typename
{
	char *ext;
	char *editor, editorstr[100];
	id	proto;

	proto = [protos protoforname:typename];
	[listbase setTitle:typename];
	ext = [proto extension];
	[savepanel setRequiredFileType:ext];
	editor = [proto editor];
	if (strcmp(editor, "") == 0)
	{
		[openineditor setTitle:""];
		[openineditor setEnabled:NO];
	}
	else
	{
		sprintf(editorstr, "Open in %s", editor);
		[openineditor setTitle:editorstr];
		[openineditor setEnabled:YES];
	}
	[defaultopen selectCellWithTag:[proto defaultopen]];
	return self;
}

// Called when the user selects a type in the pop-up-list.
- settype:sender
{
	char *typename = (char *)[[sender selectedCell] title];
	return [self setfiletype:typename];
}

// Handle service requests. The string udata is the typename..
- createNew:(id)pb userData:(const char *)udata error:(char **)ermsg
{
	char *typename;
	id	proto;
	char directory[MAXPATHLEN];
	int	tag;
	
	typename = (char *)udata;
	proto = [protos protoforname:typename];
	[self setfiletype:typename];
	
	if ([self get_dir_from_pb:directory:pb])
	{
		// Run the save panel.
		if ([savepanel runModalForDirectory:directory file:""])
		{
			char fullname[MAXPATHLEN];
			// Get the typename from the pop-up-list.
			typename = (char *)[listbase title];
			proto = [protos protoforname:typename];
			
			// Copy the file/directory
			[main copyfile:(char *)[savepanel filename]:[main fullprotoname:fullname:[proto pathname]]];
			
			// Open appropriately.
			tag = [[defaultopen selectedCell] tag];
			if (tag == OPEN_WS)
				[main openinws:(char *)[savepanel filename]];
			else if (tag == OPEN_EDITOR)
				[main openineditor:(char *)[savepanel filename]:[proto editor]];
		}
	}
	
	return self;
}


// Intercept the initialization of the listbase button to get the pop-up-list.
- setListbase:anObject;
{
	listbase = anObject;
	typelist = [listbase target];
	[typelist setTarget:self];
	[typelist setAction:@selector(settype:)];
	return self;
}

@end
